import datetime
import logging

from django import http
from django.core.paginator import Paginator, EmptyPage
from django.shortcuts import render
from django.utils import timezone
from django.views import View

from contents.utils import get_categories
from goods.models import SKU, GoodsVisitCount
from meiduo_mall.utils.response_code import RETCODE
from .models import GoodsCategory
from .utils import get_breadcrumb

# Create your views here.


logger = logging.Logger('django')


class DetailVisitView(View):
    """统计分类商品的访问量"""

    def post(self, request, category_id):
        # 接收参数和校验参数
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseForbidden("category_id参数错误")

        # 获取当前时间
        t = timezone.localtime()

        # 获取当天的时间字符串
        today_str = '%d-%02d-%02d' % (t.year, t.month, t.day)
        # 将当天的时间字符串转成时间对象datetime
        today_date = datetime.datetime.strptime(today_str, '%Y-%m-%d')

        # 判断当天中指定的分类商品对应的记录是否存在
        try:
            # 若存在则进行查询
            count_data = GoodsVisitCount.objects.get(date=today_date, category=category)
        except GoodsVisitCount.DoesNotExist:
            # 若不存在则创建
            count_data = GoodsVisitCount()

        try:
            count_data.category = category
            count_data.count += 1
            count_data.date = today_date
            count_data.save()
        except Exception as e:
            return http.HttpResponseServerError('统计失败')

        # 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


class DetailView(View):
    """商品详情页"""

    def get(self, request, sku_id):
        """商品详情页详情"""
        # 接收参数 校验参数
        try:
            sku = SKU.objects.get(id=sku_id)

        except SKU.DoesNotExist:
            return render(request, '404.html')

        # 查询商品分类
        categories = get_categories()

        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')
        # sku_specs = sku.specs.order_dy('specs_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)

        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()

        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)

            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id

            # 获取当前商品的规格信息
            goods_specs = sku.spu.specs.order_by('id')

            # 若当前sku的规格信息不完整，则不再继续
            if len(sku_key) < len(goods_specs):
                return
            for index, spec in enumerate(goods_specs):
                # 复制当前sku的规格键
                key = sku_key[:]
                # 该规格的选项
                spec_options = spec.options.all()
                for option in spec_options:
                    # 在规格参数sku字典中查找符合当前规格的sku
                    key[index] = option.id
                    option.sku_id = spec_sku_map.get(tuple(key))
                spec.spec_options = spec_options

        # 构造上下文
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'specs': goods_specs,
        }

        # 返回响应
        return render(request, 'detail.html', context)


class HotGoodsView(View):
    """热销排行"""

    def get(self, request, category_id):
        # 查询指定的分类商品的sku信息，并展示不隐藏的数据信息 并切片前两个数据
        skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]

        # 序列化
        hot_skus = []
        for sku in skus:
            hot_dict = {
                'id': sku.id,
                'default_image_url': sku.default_image.url,
                'name': sku.name,
                'price': sku.price,
            }
            hot_skus.append(hot_dict)
        # 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


class ListView(View):
    """商品列表页"""

    def get(self, request, category_id, page_num):
        # 校验参数
        try:
            # 三级id
            category = GoodsCategory.objects.get(id=category_id)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseForbidden('参数类别编号不存在')

        # 接收sort参数
        sort = request.GET.get('sort', 'default')
        # 根据sort选择排序字段，该字段必须是模型类的属性
        if sort == 'price':
            sort_field = 'price'  # 价格由低到高
        elif sort == 'hot':
            sort_field = '-sales'  # 销量由低到高
        else:
            sort = 'default'
            sort_field = 'create_time'  # 默认排序

        # 商品分类信息
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(category)

        # 分页排序和查询
        skus = category.sku_set.filter(is_launched=True).order_by(sort_field)

        # 创建分页器
        paginator = Paginator(skus, 5)
        try:
            # 获取到用户要看的那一页
            page_skus = paginator.page(page_num)
        except EmptyPage:
            return http.HttpResponseNotFound("empty page")
        # 获取总页数
        total_page = paginator.num_pages

        # 构造上下文
        context = {
            "categories": categories,  # 商品分类信息
            "breadcrumb": breadcrumb,  # 面包屑导航
            'page_skus': page_skus,  # 分页后数据
            'sort': sort,  # 排序
            'total_page': total_page,  # 总页码
            'page_num': page_num,  # 当前页码
            'category_id': category_id,
        }

        return render(request, "list.html", context)
